﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimulationPresenter.Presentation.Helpers;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;

namespace SimulationPresenter.Presentation.Primitives
{
    public class MeshShape : IPresentationPrimitive
    {
        private Mesh baseMesh;

        public bool Visible
        {
            get;
            set;
        }

        public MeshShape()
        {
            Visible = true;
            UseScale = true;
        }

        public Mesh Mesh
        {
            get { return baseMesh; }
        }

        public VertexBuffer VertexBuffer
        {
            get
            {
                return baseMesh.VertexBuffer;
            }
        }

        public IndexBuffer IndexBuffer
        {
            get
            {
                return baseMesh.IndexBuffer;
            }
        }

        public Texture Texture
        {
            get;
            set;
        }

        public Material Material
        {
            get;
            set;
        }

        public int VerticiesCount
        {
            get
            {
                return baseMesh.NumberVertices;
            }
        }

        public int indicesCount
        {
            get
            {
                return baseMesh.NumberFaces * 3;
            }
        }

        #region IPresentationMesh Members


        public CustomVertex.PositionNormalTextured[] Vertices
        {
            get;
            set;
        }

        public short[] Indices
        {
            get;
            set;
        }

        #endregion


        public static MeshShape[] FromFile(string fileName, Device device)
        {
            Texture[] textures = null;
            Material[] materials = null;
            var mesh = MeshExtensions.LoadFromFile(fileName, ref materials, ref textures, device);

            var partialMeshes = mesh.SplitMesh(device, materials, textures);

            return partialMeshes.ToArray();
        }

        #region IPresentationPrimitive Members

        public VertexFormats CustomVertexFormat
        {
            get { return CustomVertex.PositionNormalTextured.Format; }
        }

        public System.Drawing.Color Color
        {
            get;
            set;
        }

        public T[] GetVertices<T>() where T : struct
        {            
            return Vertices.Cast<T>().ToArray();
        }

        #endregion

        #region IPresentationPrimitive Members


        public Microsoft.DirectX.Vector3[] GetPositions()
        {
            return Vertices.Select(x => x.Position).ToArray();
        }
        
        public Vector3[] GetPositionsWithScale()
        {
            var vectors = Vertices.Select(x => x.Position).ToArray();
            for (int i = 0; i < vectors.Length; i++)
            {
                vectors[i].Scale(scale);
            }

            return vectors;
        }

        public float scale
        {
            get { return 10.0f; }
        }

        #endregion

        #region IPresentationPrimitive Members
        
        public void SetPositions(Vector3[] vectors)
        {
            MeshExtensions.UpdatePositions(Vertices, vectors, new MeshExtensions.PositionUpdater<CustomVertex.PositionNormalTextured>(UpdateVertex));
        }

        private void UpdateVertex(ref CustomVertex.PositionNormalTextured vertex, Vector3 vector)
        {
            vertex.Position = vector;
        }

        #endregion

        #region IPresentationPrimitive Members


        public bool UseScale
        {
            get;
            set;
        }

        #endregion
    }
}
